class_name FileSignature

# https://wikipedia.org/wiki/List_of_file_signatures


static func file_type(bytes: PoolByteArray) -> String:
	if _is_bmp(bytes):
		return "bmp"
	if _is_jpg(bytes):
		return "jpg"
	if _is_png(bytes):
		return "png"
	if _is_tga(bytes):
		return "tga"
	if _is_webp(bytes):
		return "webp"
	return ""


static func _is_bmp(bytes: PoolByteArray) -> bool:
	var bytes_0_to_1 := PoolByteArray([0x42, 0x4D])
	return bytes.subarray(0, 1) == bytes_0_to_1


static func _is_jpg(bytes: PoolByteArray) -> bool:
	var bytes_0_to_3 := PoolByteArray([0xFF, 0xD8, 0xFF, 0xDB])
	if bytes.subarray(0, 3) == bytes_0_to_3:
		return true
	
	var bytes_0_to_11 := PoolByteArray([0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10,
			0x4A, 0x46, 0x49, 0x46, 0x00, 0x01])
	if bytes.subarray(0, 11) == bytes_0_to_11:
		return true
	
	bytes_0_to_3 = PoolByteArray([0xFF, 0xD8, 0xFF, 0xEE])
	if bytes.subarray(0, 3) == bytes_0_to_3:
		return true
	
	bytes_0_to_3 = PoolByteArray([0xFF, 0xD8, 0xFF, 0xE1])
	var bytes_6_to_11 := PoolByteArray([0x45, 0x78, 0x69, 0x66, 0x00, 0x00])
	if (
			bytes.subarray(0, 3) == bytes_0_to_3
			and bytes.subarray(6, 11) == bytes_6_to_11
	):
		return true
	
	bytes_0_to_3 = PoolByteArray([0xFF, 0xD8, 0xFF, 0xE0])
	if bytes.subarray(0, 3) == bytes_0_to_3:
		return true
	
	return false


static func _is_png(bytes: PoolByteArray) -> bool:
	var bytes_0_to_7 := PoolByteArray([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A,
			0x0A])
	return bytes.subarray(0, 7) == bytes_0_to_7


static func _is_tga(bytes: PoolByteArray) -> bool:
	var bytes_17_to_0_from_end := PoolByteArray([0x54, 0x52, 0x55, 0x45, 0x56,
			0x49, 0x53, 0x49, 0x4f, 0x4e, 0x2d, 0x58, 0x46, 0x49, 0x4c, 0x45,
			0x2e, 0x00])
	return bytes.subarray(-18, -1) == bytes_17_to_0_from_end


static func _is_webp(bytes: PoolByteArray) -> bool:
	var bytes_0_to_3 := PoolByteArray([0x52, 0x49, 0x46, 0x46])
	var bytes_8_to_11 := PoolByteArray([0x57, 0x45, 0x42, 0x50])
	return (
		bytes.subarray(0, 3) == bytes_0_to_3
		and bytes.subarray(8, 11) == bytes_8_to_11
	)
